// seg_driver模块用于驱动七段显示器，显示数字或特定的符号。
module seg_driver(
    input   logic       Clk,     // 输入的时钟信号。
    input   logic       Rst_n,   // 低电平有效的复位信号。
    input   logic [18:0] data_o, // 输入的数字数据，这里假设是测得的距离数据。
    output  logic [6:0]  hex1,   // 第1个七段显示器的段选信号输出。
    output  logic [6:0]  hex2,   // 第2个...
    output  logic [6:0]  hex3,
    output  logic [6:0]  hex4,
    output  logic [6:0]  hex5,
    output  logic [6:0]  hex6,
    output  logic [6:0]  hex7,
    output  logic [6:0]  hex8     
);

// 参数定义区，定义了特殊显示值和小数点的编码，以及计数器的最大值。
parameter NOTION  = 4'd10,  // 定义数字"10"用于消隐的编码。
         FUSHU   = 4'd11,  // 定义数字"11"用作小数点的编码。
         MAX20us = 10'd1000; // 定义20微秒计数器的最大值。

// 寄存器声明区，声明了用于控制和显示数字的内部寄存器。
logic [9:0]   cnt_20us;  // 用于动态扫描定时的20微秒计数器。
logic [7:0]   sel_r;     // 动态扫描控制的片选信号寄存器。
logic [3:0]   number;    // 要显示的数字，范围0-9或特殊编码。
logic [6:0]   seg_r;     // 根据number解析得到的七段显示器段选编码。

// 每个七段显示器的段选编码寄存器，用于存储最终输出到显示器的段选编码。
logic [6:0]   hex1_r,   hex2_r,   hex3_r,   hex4_r,   hex5_r,   hex6_r,   hex7_r,   hex8_r;

// 20微秒计数器始终块，用于周期性地重置计数器来实现动态扫描。
always_ff @(posedge Clk or negedge Rst_n) begin
    if (!Rst_n) begin
        cnt_20us <= 0;  // 复位时计数器清零。
    end
    else if (cnt_20us == (MAX20us - 1)) begin
        cnt_20us <= 0;  // 计数器达到最大值时重置。
    end
    else begin
        cnt_20us <= cnt_20us + 1;  // 否则计数器递增。
    end
end

// 动态扫描控制始终块，用于生成选择当前激活的七段显示器的片选信号。
always_ff @(posedge Clk or negedge Rst_n) begin
    if (!Rst_n) begin
        sel_r <= 8'b11_11_11_10;  // 复位时初始化片选信号。
    end
    else if (cnt_20us == (MAX20us - 1)) begin
        sel_r <= {sel_r[6:0], sel_r[7]};  // 计数器达到最大值时，片选信号左移循环。
    end
    else begin
        sel_r <= sel_r;  // 否则保持当前片选信号不变。
    end
end

// 组合逻辑块，根据片选信号sel_r获取要显示的数字。
always_comb begin
    case (sel_r)
        // 根据sel_r的值选择对应的数字或特殊编码。
        // 这些编码对应于输入数据data_o的不同部分。
        // ...（此处省略了部分case语句）
        default: number = 4'd0;  // 默认情况下不显示任何数字。
    endcase
end

// 组合逻辑块，根据数字解析出对应的七段显示器段选值seg_r。
always_comb begin
    case (number)
        // 对应数字0-9的七段显示器编码。
        // ...（此处省略了部分case语句）
        NOTION: seg_r = 7'b111_1111;  // 消隐编码，所有段都不亮。
        FUSHU: seg_r = 7'b011_1111;  // 小数点编码，只点亮小数点部分。
        default: seg_r = 7'b111_1111;  // 默认消隐。
    endcase
end

// 组合逻辑块，根据片选信号sel_r将seg_r值赋给对应的七段显示器寄存器。
always_comb begin
    // 初始化所有寄存器为消隐状态。
    hex1_r = 7'b111_1111;
    hex2_r = 7'b111_1111;
    hex3_r = 7'b111_1111;
    hex4_r = 7'b111_1111;
    hex5_r = 7'b111_1111;
    hex6_r = 7'b111_1111;
    hex7_r = 7'b111_1111;
    hex8_r = 7'b111_1111;

    // 根据当前选中的显示器，将seg_r的值赋给对应的寄存器。
    case (sel_r)
        8'b11_11_11_10: hex1_r = seg_r;
        8'b11_11_11_01: hex2_r = seg_r;
        // ...（此处省略了部分case语句）
        default: ;
    endcase
end

// 将寄存器的值通过assign语句输出到端口，连接到外部的七段显示器硬件。
assign  hex1 = hex1_r;
assign  hex2 = hex2_r;
assign  hex3 = hex3_r;
assign  hex4 = hex4_r;
assign  hex5 = hex5_r;
assign  hex6 = hex6_r;
assign  hex7 = hex7_r;
assign  hex8 = hex8_r;

endmodule